package 多线程.Test;
import java.util.*;
/**
 * @Author: kirito
 * @Date: 2025/3/10 13:27
 * @Description:
 */

public class Test_taotian_24Spring {
    /*public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        int n = in.nextInt();
        int m = in.nextInt();
        String wall = in.next();

        int left = 0;
        int right = n;
        int answer = n;

        while (left <= right) {
            int mid = left + (right - left) / 2;
            if (canColorInMOperations(wall, m, mid)) {
                answer = mid; // 找到一个可行的 k，尝试更小的 k
                right = mid - 1;
            } else {
                left = mid + 1; // 当前 k 不可行，尝试更大的 k
            }
        }

        System.out.println(answer);
        in.close();
    }

    private static boolean canColorInMOperations(String wall, int m, int k) {
        int operations = 0;
        int i = 0;
        while (i < wall.length()) {
            if (wall.charAt(i) == 'W') { // 找到一个白色格子的起始位置
                // 尝试染红长度为 k 的区间
                int end = Math.min(i + k - 1, wall.length() - 1);
                while (end >= i && wall.charAt(end) == 'R') {
                    end--; // 找到区间内最后一个白色格子的位置
                }
                if (end < i) { // 没有找到白色格子，无法进行染色
                    return false;
                }
                operations++; // 进行一次染色操作
                i = end + 1; // 移动到下一个区间
                if (operations > m) { // 操作次数超过 m，失败
                    return false;
                }
            } else {
                i++; // 当前格子已经是红色，移动到下一个格子
            }
        }
        return true; // 成功在 m 次操作内将墙染红
    }*/
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        int n = in.nextInt(); // 读取数组的长度
        int[] nums = new int[n];
        for (int i = 0; i < n; i++) {
            nums[i] = in.nextInt(); // 读取数组元素
        }
        int ans = resolve(nums); // 调用 resolve 方法来解决问题

        System.out.println(ans); // 输出结果
        in.close(); // 关闭扫描器
    }

    // 解决问题的核心方法
    private static int resolve(int[] nums) {
        int n = nums.length;
        if (n <= 1) {
            return n; // 如果数组长度小于等于1，直接返回数组长度
        }
        boolean[] left = new boolean[n]; // 标记从左到右是否为非降序
        boolean[] right = new boolean[n]; // 标记从右到左是否为非升序
        left[0] = true; // 第一个元素默认为非降序
        // 判断从左到右是否为非降序
        for(int i = 1; i < n && left[i-1]; i++){
            left[i] = nums[i] >= nums[i-1];
        }

        right[n-1] = true; // 最后一个元素默认为非升序
        int t = n - 1; // 记录从右到左最后一个非升序的索引
        // 判断从右到左是否为非升序
        for(int i = n - 2; i >= 0 && right[i+1]; i--){
            right[i] = nums[i] <= nums[i+1];
            if(right[i]){
                t = i; // 更新最后一个非升序的索引
            }
        }
        int ans = n - t + 1; // 计算从 t 到数组末尾的长度
        // 遍历数组，计算所有可能的区间删除方案
        for(int l = 0 ; l < n ; l++){
            if(!left[l]){ // 如果当前元素不满足非降序，则跳出循环
                break;
            }
            // 获取第一个大于 nums[l] 的元素的索引
            int r = getFirstLager(nums[l],nums,Math.max(l+1,t),n-1);
            ans += n - r + 1; // 累加从 r 到数组末尾的长度
        }
        return ans; // 返回总的区间删除方案数
    }

    // 二分查找第一个大于目标值的元素的索引
    private static int getFirstLager(int minValue, int[] nums , int left, int right){
        while(left <= right){
            int mid = ( left + right) >> 1; // 计算中间索引
            if(nums[mid] >= minValue){ // 如果中间值大于等于目标值，搜索左半部分
                right = mid - 1;
            }else{ // 否则搜索右半部分
                left = mid + 1;
            }
        }
        return left; // 返回第一个大于目标值的元素的索引
    }
        /*public static void main(String[] args) {
            Scanner in = new Scanner(System.in);
            int n = in.nextInt(); // 账号个数
            int m = in.nextInt(); // 比赛记录数

            int ans = Integer.MIN_VALUE;
            // 使用优先队列（最小堆）存储账号分数
            PriorityQueue<Integer> pq = new PriorityQueue<>();

            // 读取账号分数并加入优先队列
            for (int i = 0; i < n; i++) {
                int a = in.nextInt();
                ans = Math.max(ans, a);
                pq.add(a);
            }

            // 读取比赛分数变化
            int[] changes = new int[m];
            for (int i = 0; i < m; i++) {
                changes[i] = in.nextInt();
            }

            // 处理每次比赛并输出maxRating
            for (int change : changes) {
                // 从优先队列中取出最小分数的账号
                int minRating = pq.poll();
                // 更新分数
                minRating += change;
                ans = Math.max(ans, minRating);
                // 将更新后的分数放回优先队列
                pq.add(minRating);
                // 输出当前最高分数，即优先队列中的最大元素
                System.out.println(ans);
            }

            in.close();
        }*/
}
